home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ansi / hercules.zip / HERCDEMO.ASM < prev    next >
Assembly Source File  |  1986-09-06  |  8KB  |  336 lines

  1.         page    ,132
  2.     title    hercdemo - quick and dirty herc demo
  3. ;
  4. ; Hercdemo - (c) 1986 by Reid Brown, P.O. Box 1023, Issaquah, WA.  98027
  5. ;
  6. ;    This is a quick and dirty program to show off the Hercules
  7. ;    board.  I place if freely into the public domain so others
  8. ;    can diddle their Herc boards as well, so long as it is not
  9. ;    used for any commercial purposes.
  10. ;
  11.  
  12. message    macro    row,col,string
  13.     mov    cx,row
  14.     mov    bx,col
  15.     mov    si,offset string
  16.     call    print
  17.         endm
  18.  
  19. hdraw    macro    row,col,len
  20.     mov    cx,row
  21.     mov    bx,col
  22.     mov    dx,len
  23.     call    hline
  24.         endm
  25.  
  26. vdraw    macro    row,col,len
  27.     mov    cx,row
  28.     mov    bx,col
  29.     mov    dx,len
  30.     call    vline
  31.         endm
  32.  
  33. code    segment
  34.     assume    cs:code, ds:code, es:code, ss:code
  35.         org     100h
  36. start:    jmp    begin
  37.  
  38. IBMROM    equ    0F000h
  39. CHARTAB    equ    0FA6Eh
  40. HERCSEG    equ    0B800h
  41.  
  42. MODEPORT equ    3B8h
  43.  
  44. STRING0 db      'HERCULES DEMO',0
  45. STRING1    db    'A funny thing happened on the way to the forum.',0
  46. STRING2    db    'You, too, can have a rewarding career in computers...',0
  47. STRING3 db      'Strike any key to proceed...',0
  48.  
  49.  
  50. CON8    db    8
  51. CON180    db    180
  52.  
  53. begin    proc    near
  54.     mov    dx, MODEPORT        ; select herc mode port
  55.     mov    al, 08Ah
  56.     out    dx, al            ; graphics mode, video on, page 1
  57.  
  58.     call    graphics        ; set 6845 for graphics
  59.         call    clear            ; clear screen RAM
  60.  
  61.         vdraw   10,5,20                 ; draw a vertical
  62.         vdraw   10,65,20                ; - hopefully, a box!
  63.         hdraw   10,6,60                 ; draw a line
  64.         hdraw   30,6,60                 ; and another
  65.  
  66.         message 12,29,STRING0           ; 1st message
  67.         message 17,10,STRING1           ; 2nd message
  68.         message 23,10,STRING2           ; 3nd message
  69.         message 29,20,STRING3           ; ...
  70.         
  71. ;
  72. ; done - clean up and reset
  73. ;
  74.         mov    ax, 0C07h        ; flush buffer, read char
  75.     int    21h            ; wait for any input
  76.  
  77.         call    text                    ; reset 6845
  78.  
  79.     mov    dx, MODEPORT        ; select herc mode port
  80.     mov    al, 00001000B        ; re-enable mono
  81.     out    dx, al
  82.         
  83.     mov    ax, 4C00h
  84.     int    21h            ; exit
  85. begin    endp
  86.  
  87. ;
  88. ; print - print text in graphics mode
  89. ;
  90. ;    cx = row
  91. ;    bx = column
  92. ;    si = address of string (null terminated) to print
  93. ;
  94. print    proc    near
  95.  
  96. loop:    lodsb                ; get next char
  97.     or    al, al            ; end of display?
  98.     je    pdone
  99.     call    display
  100.     inc    bx            ; bump to next column
  101.     jmp    loop
  102. pdone:    ret
  103.  
  104. print    endp
  105.  
  106. ;
  107. ; display - output an 8x8 character from the IBM ROM to the Herc board
  108. ;
  109. ; AX = char, BX = column (0-89), CX = row(0-42)  ** all preserved **
  110. ;
  111. display    proc near
  112.     push    ds            ; save the lot
  113.     push    es
  114.     push    ax
  115.     push    bx
  116.     push    cx
  117.     push    dx
  118.     push    si
  119.     push    di
  120.  
  121. ; setup ds -> IBM ROM, and si -> index into IBM ROM character table located
  122. ;    at 0fa6eh in the ROM
  123.  
  124.     and    ax, 07fh
  125.     mul    CS:CON8            ; mult by 8 bytes of table per char
  126.     mov    si, ax
  127.     mov    ax, IBMROM
  128.     mov    ds, ax
  129.     assume    ds:nothing
  130.     add    si, CHARTAB        ; add offset of character table
  131.  
  132. ; compute index into Hercules screen memory for scan line 0.  The remaining
  133. ;    seven scan lines are all at fixed offsets from the first.
  134. ;
  135. ;    Since graphics mode treats the screen as sets of 16x4 "characters",
  136. ;    we need to map an 8x8 real character onto the front or back of
  137. ;    a pair of graphics "characters".  The first four scan lines of our
  138. ;    8x8 character will map to the top graphics "character", and the second
  139. ;    four scan lines map to the graphics character on the "line" (4 scan
  140. ;    lines high) below it.
  141. ;
  142. ;    For some exotic hardware reason (probably speed), all scan line 0
  143. ;    bits (i.e. every fourth scan line) are stored in memory locations
  144. ;    0-2000h in the screen buffer.  All scan line 1 bits are stored
  145. ;    2000h-4000h.  Within these banks, they are stored by rows.  The first
  146. ;    scan line on the screen (scan line 0 of graphics character row 0)
  147. ;    is the first 45 words of memory in the screen buffer.  The next 45
  148. ;    words are the first scan line graphics row 1, and since graphics
  149. ;    "characters" are 4 bits high, this second scan line is physically
  150. ;    the fifth scan line displayed on the screen.
  151. ;
  152. ;    SO, to display an 8x8 character, the 1st and 5th rows of dots are
  153. ;    both scan line 0 of the graphics "character", the 2nd and 6th are
  154. ;    scan line 1, and so on.
  155. ;
  156. ;    The column (0-89) tells which byte in a scan line we need to load.
  157. ;    Since it takes two rows of graphics characters to hold one row of
  158. ;    our characters, column+90 is a index to scan line 4 rows of pixels
  159. ;    higher (n+4).  Thus 180 bytes of screen memory in any bank (0h, 2000h,
  160. ;    4000h, 6000h) represent a row of 8x8 characters.
  161. ;    
  162. ;    The starting location in screen memory for the first scan line of
  163. ;    a character to be displayed will be:      (row*180)+column
  164. ;    The 5th scan line will be at:        (row*180)+column+90
  165. ;
  166. ;    The second and 6th scan lines will be at the above offsets plus
  167. ;    the bank offset of 2000h.  The third and 7th, add 4000h and finally
  168. ;    the 4th and 8th, add 6000h.
  169. ;
  170.     mov    ax, HERCSEG
  171.     mov    es, ax            ; es = hercules page 0
  172.     mov    ax, cx            ; get row
  173.     mul    CS:CON180        ; mult by 180(10)
  174.     mov    di, ax            ; di = index reg
  175.     cld                ; insure right direction
  176.  
  177. ;output 8 segments of character to video ram
  178.  
  179.     lodsb                ; line 0
  180.     mov    es:[di+bx], al
  181.     lodsb
  182.     mov    es:[di+bx+2000h], al    ; line 1
  183.     lodsb
  184.     mov    es:[di+bx+4000h], al    ; line 2
  185.     lodsb
  186.     mov    es:[di+bx+6000h], al    ; line 3
  187.     lodsb
  188.     mov    es:[di+bx+90], al    ; line 4
  189.     lodsb
  190.     mov    es:[di+bx+2000h+90], al    ; line 5
  191.     lodsb
  192.     mov    es:[di+bx+4000h+90], al    ; line 6
  193.     lodsb
  194.     mov    es:[di+bx+6000h+90], al    ; line 7
  195.  
  196.     pop    di
  197.     pop    si
  198.     pop    dx
  199.     pop    cx
  200.     pop    bx
  201.     pop    ax
  202.     pop    es
  203.     pop    ds
  204.     ret
  205. display    endp
  206.  
  207. ;
  208. ; clear - clear page 1 of the screen buffer to zero (effectively, blank
  209. ;    the screen)
  210. ;
  211. clear   proc
  212.         push    es
  213.         push    ax
  214.         push    cx
  215.         push    di
  216.  
  217.     mov    ax, HERCSEG
  218.     mov    es, ax
  219.     xor    di, di
  220.     mov    cx, 4000h
  221.     xor    ax, ax
  222.     cld
  223.  
  224.     rep stosw            ; zero out screen page
  225.     
  226.     pop    di
  227.     pop    cx
  228.     pop    ax
  229.     pop    es
  230.     ret
  231. clear    endp
  232.  
  233. ;
  234. ; hline - draw a horizontal line at scan line 0 of a specified 8x8 character
  235. ;    cell sized row, for a specified no. of characters
  236. ;
  237. ;    cx = row
  238. ;    bx = col
  239. ;    dx = len
  240. ;
  241. hline    proc near
  242.         push    es
  243.         push    ax
  244.         push    cx
  245.         push    di
  246.  
  247.     mov    ax,cx            ; copy to accum for multiply
  248.     mul    cs:CON180        ; mult by 180 to get offset
  249.     mov    di,ax            ; copy to dest ptr
  250.     add    di,bx            ; add column offset
  251.     mov    cx,dx            ; put byte count in count reg
  252.     mov    ax, HERCSEG
  253.     mov    es, ax
  254.         mov     ax, 0ffh        ; pattern = all bits ON
  255.     cld
  256.  
  257.     rep stosb            ; put bits on screen
  258.     
  259.     pop    di
  260.     pop    cx
  261.     pop    ax
  262.     pop    es
  263.     ret
  264.  
  265. hline    endp
  266.  
  267. ;
  268. ; vline - draw a vertical line in the last bit position of a given char
  269. ;    cell, extending downward for a specified no. of chars
  270. ;
  271. ;    cx = row
  272. ;    bx = col
  273. ;    dx = len
  274. ;
  275. vline    proc near
  276.         push    es
  277.         push    ax
  278.         push    cx
  279.         push    di
  280.  
  281.     mov    ax,cx            ; copy to accum for multiply
  282.     mul    cs:CON180        ; mult by 180 to get offset
  283.     mov    di,ax            ; copy to dest ptr
  284.     mov    cx,dx            ; put byte count in count reg
  285.     mov    ax, HERCSEG
  286.     mov    es, ax
  287.         mov     ax, 1            ; pattern = last bit on
  288.  
  289. vloop:    mov    es:[di+bx], al
  290.     mov    es:[di+bx+2000h], al    ; line 1
  291.     mov    es:[di+bx+4000h], al    ; line 2
  292.     mov    es:[di+bx+6000h], al    ; line 3
  293.     mov    es:[di+bx+90], al    ; line 4
  294.     mov    es:[di+bx+2000h+90], al    ; line 5
  295.     mov    es:[di+bx+4000h+90], al    ; line 6
  296.     mov    es:[di+bx+6000h+90], al    ; line 7
  297.     add    di,180                ; advance to next line
  298.     loop    vloop            ; continue for all rows
  299.     
  300.     pop    di
  301.     pop    cx
  302.     pop    ax
  303.     pop    es
  304.     ret
  305.  
  306. vline    endp
  307.  
  308. graphics proc near
  309.     mov    si, offset graph_parms
  310. g_cont:    mov    dx, 3b4h        ; point to index reg
  311.     mov    cx, 16
  312.     xor    ax, ax
  313. g_loop:    mov    al, ah
  314.     out    dx, al
  315.     inc    dx
  316.     mov    al, [si]
  317.     out    dx, al
  318.     dec    dx
  319.     inc    ah
  320.     inc    si
  321.     loop    g_loop
  322.     ret
  323. graph_parms db    35h,2dh,2eh,7,5bh,2,57h,57h,2,3,0,0,0,0,0,0
  324. graphics endp
  325.  
  326. text    proc    near
  327.     mov    si, offset text_parms
  328.     jmp    g_cont
  329. text_parms db    61h,50h,52h,0fh,19h,6,19h,19h,2,0dh,0bh,0ch,00,00,00,00
  330. text    endp
  331.  
  332.  
  333. code    ends
  334.  
  335.     end    start
  336.